<template>
  <div v-if="generated === false">
    <!-- 头部 -->
    <div class="header-content">
      <div style="display: flex; align-items: center; justify-content: center">
        <img src="/icon/command.svg" style="width: 40px; margin-right: 4px" />
        <h1 v-text="displayedText" class="typewriter-text"></h1>
      </div>
      <div style="margin-top: 4px; color: #666; font-size: 12px">
        Mybatis在线生成器 | JPA代码生成器 | MYBATIS模板代码生成平台
      </div>
    </div>

    <a-spin :spinning="fileLoading">
      <div
        style="
          width: 100%;
          display: flex;
          align-items: center;
          justify-content: center;
          margin: 20px 0;
        "
      >
        <a-button
          @click="showConfigModal"
          type="primary"
          size="large"
          danger
          style="width: 120px"
          :loading="loading"
        >
          立即生成
        </a-button>
      </div>

      <!-- 内容区域 -->
      <div style="width: 100%; display: flex; justify-content: center">
        <!-- 消息发送区域 -->
        <div style="width: 90%" class="editor">
          <div class="code-tool-bar">
            <a-upload
              :custom-request="customRequest"
              :show-upload-list="false"
              :max-count="1"
              :beforeUpload="handleFileChange"
            >
              <div style="display: flex; align-items: center; color: #ffffff">
                <LinkOutlined class="upload-btn" />
                <div class="file-name">导入文件</div>
              </div>
            </a-upload>

            <div style="margin-left: 24px; cursor: pointer; display: flex; align-items: center">
              <img src="/icon/template.svg" style="width: 16px" />
              <a
                style="margin-left: 4px; color: #ffffff; font-size: 12px"
                target="_blank"
                href="/#/code-template"
              >
                自定义模板
              </a>
            </div>

            <div style="margin-left: 24px; cursor: pointer; display: flex; align-items: center">
              <img src="/icon/history.svg" style="width: 16px" />
              <a
                style="margin-left: 4px; color: #ffffff; font-size: 12px"
                @click="showHistoryModal"
              >
                生成记录
              </a>
            </div>
          </div>

          <common-editor
            height="calc(100vh - 240px)"
            @change="inputChange"
            :content="input"
            mode="sql"
            placeholder="输入SQL / 需求"
            theme="solarized_dark"
          />
        </div>
      </div>
    </a-spin>

    <a-modal
      v-model:open="configModalVisible"
      title=""
      width="800px"
      :footer="null"
      :closable="false"
    >
      <code-generate-config
        v-if="configModalVisible"
        :handleCancel="handleCancel"
        :handleGenerate="generateCode"
      />
    </a-modal>

    <a-modal
      v-model:open="historyVisible"
      title="代码生成记录"
      width="1000px"
      :footer="null"
      :mask-closable="false"
      :closable="true"
      @cancel="handleCancel"
    >
      <!-- 表格容器 -->
      <div v-if="historyData">
        <a-table
          :columns="columns"
          :data-source="historyData"
          :pagination="false"
          :loading="loading"
          size="middle"
          :row-key="(record) => record.id"
        >
          <template #bodyCell="{ record, column }">
            <template v-if="column.key === 'action'">
              <div style="display: flex; align-items: center">
                <a-button size="small" type="primary" @click="handleViewInput(record)">
                  <template #icon><EyeOutlined /></template>
                  输入
                </a-button>
                <a-button
                  size="small"
                  type="default"
                  @click="handleViewOutput(record)"
                  style="margin-left: 8px"
                >
                  <template #icon><ExportOutlined /></template>
                  输出
                </a-button>
              </div>
            </template>
          </template>
        </a-table>

        <!-- 分页器 -->
        <div class="pagination-container">
          <a-pagination
            v-model:current="pageParams.current"
            v-model:page-size="pageParams.pageSize"
            :total="pageParams.total"
            show-quick-jumper
            :show-total="(total) => `共 ${total} 条记录`"
            @change="handlePageChange"
          />
        </div>
      </div>

      <div v-else>
        <a-skeleton active class="message-ai" />
      </div>
    </a-modal>
  </div>
  <code-tree :files="files" v-if="generated === true && files.length > 0" @close="closeTree" />
</template>

<script setup>
import Http from '@/api/http'
import { isLogin } from '@/stores/user'
import CodeTree from '@/views/component/code-tree.vue'
import commonEditor from '@/views/component/common-editor.vue'
import { ExportOutlined, EyeOutlined, LinkOutlined } from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import { onMounted, onUnmounted, ref } from 'vue'
import CodeGenerateConfig from '@/views/component/code-generate-config.vue'

// 要显示的完整文本
const fullText = '您的智能代码生成器'
// 当前显示的文本（初始为空）
const displayedText = ref('')
// 打字机效果的速度（毫秒）
const typingSpeed = 100 // 可以调整速度

// 模拟打字机效果的函数
const typeWriter = () => {
  let i = 0
  const timer = setInterval(() => {
    // 逐个添加字符
    if (i < fullText.length) {
      displayedText.value += fullText.charAt(i)
      i++
    } else {
      // 文本显示完毕，清除定时器
      clearInterval(timer)
    }
  }, typingSpeed)
}

// SSE 实例
let eventSource = null
const clientId = ref(null)
const stopFlag = ref(false)
const loading = ref(false)
// 响应式数据
const input = ref('')
const btnLoading = ref(false)
const configModalVisible = ref(false)
const model = ref('deepseek-v3-250324')
const sessionId = ref(null)
const generated = ref(false)
const file = ref(null)
const fileName = ref('')
const fileContent = ref('')
const fileLoading = ref(false)

const historyVisible = ref(false)
const historyData = ref(null)
const pageParams = ref({
  current: 1,
  pageSize: 5,
  total: 0
})
// 表格列定义
const columns = [
  {
    title: '输入',
    dataIndex: 'input',
    key: 'input',
    width: 200,
    ellipsis: true
  },
  {
    title: '输出',
    dataIndex: 'output',
    key: 'output',
    width: 200,
    ellipsis: true
  },
  {
    title: '生成时间',
    dataIndex: 'createdDate',
    width: 160,
    key: 'createdDate'
  },
  {
    title: '操作',
    dataIndex: 'action',
    key: 'action',
    width: 120,
    fixed: 'right'
  }
]

function handleViewInput(record) {
  historyVisible.value = false
  input.value = record.input
}

function handleViewOutput(record) {
  historyVisible.value = false
  files.value = JSON.parse(record.output)
  generated.value = true
  loading.value = false
}

// 分页改变处理
const handlePageChange = (page, pageSize) => {
  pageParams.value.current = page
  Http.post('/api/generateCodeLog/findPage', pageParams.value).then((res) => {
    historyData.value = res.data.records
    pageParams.value.total = res.data.total
  })
}

function closeTree() {
  generated.value = false
  files.value = []
}

function showHistoryModal() {
  historyVisible.value = true
  Http.post('/api/generateCodeLog/findPage', pageParams.value).then((res) => {
    historyData.value = res.data.records
    pageParams.value.total = res.data.total
  })
}

function inputChange(value) {
  input.value = value
}

const handleCancel = () => {
  configModalVisible.value = false
}

const files = ref([])

function customRequest() {
  const formData = new FormData()
  // 2. 将文件添加到 FormData，'file' 是后端接收时使用的字段名
  formData.append('file', file.value)
  fileLoading.value = true
  Http.post('/api/file/readFile', formData)
    .then((res) => {
      input.value = res
    })
    .catch((err) => {
      message.error(err)
    })
    .finally((res) => {
      fileLoading.value = false
    })
}

function handleFileChange(fileData) {
  file.value = fileData
  fileName.value = fileData.name
}

// 显示配置对话框
const showConfigModal = () => {
  if (!input.value.trim()) {
    message.warning('请输入SQL或需求')
    return
  }
  configModalVisible.value = true
}

// 生成代码逻辑
const generateCode = (generatorConfig) => {
  const requestParams = {
    modelName: model.value,
    chatId: generateId(),
    clientId: clientId.value,
    sessionId: sessionId.value,
    content: input.value,
    toolType: 'crud',
    toolParams: {
      javaCodeConfig: generatorConfig
    }
  }
  if (fileContent.value) {
    requestParams['fileContent'] = fileContent.value
  }
  stopFlag.value = false
  btnLoading.value = true
  Http.post('/api/chat/stream', requestParams)
    .then((res) => {
      btnLoading.value = false
      configModalVisible.value = false
      loading.value = true
    })
    .catch((err) => {
      loading.value = false
      stopFlag.value = false
      message.error('系统异常，请联系站长')
    })
}

/**
 * 生成随机ID
 */
function generateId() {
  const timestamp = Date.now() // 毫秒级时间戳
  const randomNum = Math.floor(Math.random() * 10000) // 0-9999 的随机数
  return `${timestamp}${randomNum}`
}

onMounted(() => {
  typeWriter()
  if (!isLogin) {
    return
  }
  clientId.value = generateId()
  sessionId.value = generateId()
  const sseUrl = Http.baseUrl + '/sse/event/connect?clientId=' + clientId.value
  eventSource = new EventSource(sseUrl)
  // 监听 message 事件（默认事件）
  eventSource.onmessage = (event) => {
    if (event.data === 'event: stop' || stopFlag.value === true) {
      loading.value = false
      return
    }
    try {
      const data = JSON.parse(event.data)
      if (data.file && loading.value) {
        files.value = JSON.parse(data.file)
        generated.value = true
        loading.value = false
        message.success('代码生成成功')
      }
    } catch (err) {
      console.error(err)
    }
  }
  // 监听自定义事件
  eventSource.addEventListener('complete', (event) => {
    loading.value = false
  })
  // 错误处理
  eventSource.onerror = (err) => {
    console.error('SSE error:', err)
    loading.value = false
  }
})

onUnmounted(() => {
  if (eventSource) {
    eventSource.close()
  }
})
</script>

<style scoped>
.header-content {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 20px;
}

.config-modal :deep(.ant-modal-body) {
  max-height: 60vh;
  overflow-y: auto;
}

.editor {
  width: 100%;
}

.ant-input {
  overflow-y: hidden;
}

.ant-input:hover {
  overflow-y: auto;
}

.upload-btn {
  font-size: 14px;
}

.upload-btn :hover {
  color: #1677ff;
}

.typewriter-container {
  /* 可以根据需要调整容器样式 */
  padding: 20px;
  text-align: center;
}

.typewriter-text {
  letter-spacing: 1.2px;
  font-family:
    -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', sans-serif;
  font-size: 2rem;
  font-weight: 600;
  color: #5d00ff;
  line-height: 1;
  padding-right: 4px;
  animation: blink 0.8s step-end infinite;
  margin: 0;
}
@keyframes blink {
  0%,
  100% {
    border-color: #555; /* 闪烁时颜色不变，只是透明度变 */
    opacity: 1;
  }
  50% {
    border-color: #555;
  }
}

.file-name {
  margin-left: 4px;
  cursor: pointer;
  max-width: 100px;
  white-space: nowrap; /* 不换行 */
  overflow: hidden; /* 超出部分隐藏 */
  text-overflow: ellipsis; /* 超出部分显示省略号 */
  font-size: 12px;
}

.code-tool-bar {
  width: 100%;
  display: flex;
  align-items: center;
  background: #9a4301;
  color: #ffffff;
  padding: 4px 12px;
}
</style>
